package com.sinodata.bsm.center.engine.event;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

import com.sinodata.bsm.center.bean.EventRuleBean;
import com.sinodata.bsm.center.bean.ResBean;
import com.sinodata.bsm.center.cache.EventTypeCache;
import com.sinodata.bsm.center.cache.NewEventCache;
import com.sinodata.bsm.center.service.event.EventService;
import com.sinodata.bsm.center.util.spring.SpringContextHolder;
import com.sinodata.bsm.common.constants.EventConstants;
import com.sinodata.bsm.common.vo.Event;

/**
 * 
 * <p>
 * Description:可恢复事件规则组 
 * </p>
 *
 * @author liulibo
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-5-29 AM 10:34:04    liulibo        1.0         To create
 * </p>
 *
 * @since 
 * @see
 */
public class ResumableRuleGroup extends EventRuleGroup {

    protected static Logger logger = Logger.getLogger(ResumableRuleGroup.class);

    private static NewEventCache newEventCache = SpringContextHolder.getBean(NewEventCache.class);

    private static EventService eventService = SpringContextHolder.getBean(EventService.class);

    private static EventTypeCache eventTypeCache = SpringContextHolder.getBean(EventTypeCache.class);

    private int status = EventConstants.LEVEL_NORMAL;

    public ResumableRuleGroup(Long resId, Long typeId) {
        super(resId, typeId);
    }

    /**
     * 匹配事件
     */
    @Override
    public List<Event> matches(Long resId, Long propId) {
        //先看规则能不能产生事件
        //this.ruleStatus = false;//eventRuleBean.matching();
        //原匹配事件
        List<Event> events = new ArrayList<Event>();
        int level = EventConstants.LEVEL_NORMAL;
        if (rules == null || rules.size() == 0) {
            // System.out.println("事件因事件规则修改或删除被系统自动清除");
            events.add(this.makeClearEvent());
        }
        for (Iterator<EventRuleBean> i = rules.iterator(); i.hasNext();) {
            EventRuleBean rule = i.next();
            rule.matching();//外部引擎不去进行匹配了，改为此处进行匹配
            //
            //System.out.print("匹配的事件规则级别：" + rule.getEventLevle() + " 事件规则状态" + rule.getStatus());
            if (rule.isAvailable() && rule.getStatus()) {//ruleStatus
                //
                // System.out.print("有效的事件规则级别：" + rule.getEventLevle() + " 事件规则状态" + rule.getStatus());
                if (level < rule.getEventLevle()) {
                    level = rule.getEventLevle();
                }
            }
        }
        if (status != EventConstants.LEVEL_NORMAL && level == EventConstants.LEVEL_NORMAL) {
            events.add(this.makeResumeEvent(status, level));
        } else if (status != level) {
            if (status > level) {
                events.add(this.makeResumeEvent(status, level));
            }
            for (Iterator<EventRuleBean> i = rules.iterator(); i.hasNext();) {
                EventRuleBean rule = i.next();
                if (rule.getEventLevle() == level) {
                    try {
                        events.add(rule.makeEvent(null));
                        break;
                    } catch (Exception e) {
                        logger.error("failed to create event ", e);
                    }
                }
            }
        } else if (status != EventConstants.LEVEL_NORMAL && status == level) {
            //如果事件存在，压制，加入产生次数，和最后产生时间
            List<Event> eventtmp = newEventCache.getNewEvents(this.resId, this.eventTypeId, null);
            Event tmp = null;
            for (int i = 0; eventtmp != null && i < eventtmp.size(); i++) {
                tmp = eventtmp.get(i);
                if (tmp != null && tmp.getLevel() == status) {
                    int cnt = tmp.getCount();
                    if (cnt <= 0) {
                        tmp.setCount(1);
                        tmp.setLastOccurTime(tmp.getOccurTime());
                    } else {
                        tmp.setCount(cnt + 1); //同一引用次处已更新缓存
                        tmp.setLastOccurTime(new Date());
                    }
                    //更新事件个数
                    eventService.update(tmp);
                }
            }
        }
        this.status = level;
        return events;
    }

    /**
     * 产生一个正常事件
     * 
     * @return
     */
    private Event makeResumeEvent(int beforeLevel, int afterLevel) {
        Event event = new Event();
        event.setResId(resId);
        event.setEventTypeId(eventTypeId);
        event.setLevel(beforeLevel);
        StringBuilder msg = new StringBuilder();
        if (ResBean.get(resId).res().getIp() != null) {
            msg.append(ResBean.get(resId).res().getIp());
            msg.append(" ");
        }
        msg.append(ResBean.get(resId).res().getName());
        msg.append(" ");
        msg.append(eventTypeCache.get(eventTypeId).getName());
        msg.append("事件由");
        msg.append(EventConstants.getLevelDesc(beforeLevel));
        msg.append("恢复到");
        msg.append(EventConstants.getLevelDesc(afterLevel));
        event.setMsg(msg.toString());
        event.setOccurTime(new Date());
        event.setStatus(EventConstants.STATUS_CONFIRMED);
        event.setCatalog(EventConstants.CATALOG_REFAULTEVENT);
        return event;
    }

    /**
     * 规则删除后清除事件
     * 
     * @return
     */
    private Event makeClearEvent() {
        Event event = new Event();
        event.setResId(resId);
        event.setEventTypeId(eventTypeId);
        event.setLevel(-1);
        StringBuilder msg = new StringBuilder();
        if (ResBean.get(resId).res().getIp() != null) {
            msg.append(ResBean.get(resId).res().getIp());
            msg.append(" ");
        }
        msg.append(ResBean.get(resId).res().getName());
        msg.append(" ");
        msg.append(eventTypeCache.get(eventTypeId).getName());
        msg.append("事件因事件规则修改或删除被系统自动清除");
        event.setMsg(msg.toString());
        event.setOccurTime(new Date());
        event.setStatus(EventConstants.STATUS_CONFIRMED);
        event.setCatalog(EventConstants.CATALOG_RULE_CLEAR);
        return event;
    }

    /**
     * 设置初始化状态
     * 
     * @param status
     */
    public void setStatus(int status) {
        this.status = status;
    }

}